package tpsi.pong;

import java.awt.Point;
import java.util.ArrayList;
import java.util.HashMap;

public class Game {
	private ArrayList<Player> players;
	private HashMap<Player, Paddle> paddles;
	private Player owner;
	private GameState gameState;
	private Ball ball;
	private String name;
	private int scoreA;
	private int scoreB;

	public Game() {
		this.players = new ArrayList<Player>(4);
		this.paddles = new HashMap<Player, Paddle>();
		this.setOwner(null);
		this.setGameState(GameState.PAUSED);
		this.ball = new Ball();
		this.setName(null);
		this.scoreA = 0;
		this.scoreB = 0;
	}

	public Game(Player p) {
		this();
		this.setOwner(p);
		this.players.add(p);
		p.setCurrentGame(this);
		this.paddles.put(p, new Paddle(PaddleColor.RED));
	}

	private void notyfyOtherPlayers(Player p) {
		if (this.players.size() > 0) {
			StringBuilder sb = new StringBuilder();
			sb.append(p.getPlayerMsg());
			sb.append("\nJOINED\n1");
			String s = sb.toString();
			for (int i = 0; i < this.players.size(); ++i) {
				Player pl = this.players.get(i);
				pl.sendMsg(s);
			}
		}
	}

	public void addPlayer(Player p) {
		if ((this.players.size() < 4) && (this.gameState != GameState.STARTED)) {
			this.notyfyOtherPlayers(p);
			this.players.add(p);
			p.setCurrentGame(this);
			switch (this.players.size()) {
			case 1:
				this.paddles.put(p, new Paddle(PaddleColor.RED));
				break;
			case 2:
				this.paddles.put(p, new Paddle(PaddleColor.GREEN));
				break;
			case 3:
				this.paddles.put(p, new Paddle(PaddleColor.BLUE));
				break;
			case 4:
				this.paddles.put(p, new Paddle(PaddleColor.YELLOW));
				break;
			default:
				this.paddles.put(p, new Paddle(PaddleColor.WHITE));
			}
		}
	}

	public void removePlayer(Player p) {
		p.setCurrentGame(null);
		this.players.remove(p);
		this.paddles.remove(p);
	}

	public void removeAllPlayers() {
		for (int i = this.players.size() - 1; i >= 0; --i) {
			Player p = this.players.get(i);
			p.setCurrentGame(null);
			this.players.remove(i);
			this.paddles.remove(p);
		}
	}

	public void setOwner(Player owner) {
		this.owner = owner;
	}

	public Player getOwner() {
		return owner;
	}

	public void setGameState(GameState gameState) {
		this.gameState = gameState;
	}

	public GameState getGameState() {
		return gameState;
	}

	public String getSTATEMsg() {
		StringBuilder sb = new StringBuilder();
		sb.append("STATE\n");
		sb.append(this.gameState.toString());
		return sb.toString();
	}

	public String getJoinedPlayers() {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < this.players.size(); ++i) {
			Player p = this.players.get(i);
			if (i != 0)
				sb.append("\n");
			sb.append(p.getPlayerMsg());
			sb.append("\nJOINED\n1");
		}
		return sb.toString();
	}

	public int getPlayersCount() {
		return this.players.size();
	}

	public void playerStatusChanged() {
		GameState ready = GameState.READY;
		for (int i = 1; i < this.players.size(); ++i) {
			Player p = this.players.get(i);
			if (p.getState() != GameState.READY) {
				ready = GameState.PAUSED;
				break;
			}
		}
		if (this.gameState != ready) {
			this.setGameState(ready);
			sendMsgToAll(this.getSTATEMsg());
		}
	}

	public void sendMsgToAll(String msg) {
		for (int i = 0; i < this.players.size(); ++i) {
			Player p = this.players.get(i);
			p.sendMsg(msg);
		}
	}

	public Paddle getPlayerPaddle(Player p) {
		return this.paddles.get(p);
	}

	public void setBall(Ball ball) {
		this.ball = ball;
	}

	public void setBallPos(String msg) throws NumberFormatException {
		String[] pos = msg.split(":");
		Point p = this.ball.getPos();
		p.setLocation(Integer.parseInt(pos[0]), Integer.parseInt(pos[1]));
	}

	public void setBallSpeed(String msg) throws NumberFormatException {
		String[] speed = msg.split(":");
		this.ball.setSpeed(Integer.parseInt(speed[0]), Integer
				.parseInt(speed[1]));
	}

	public Ball getBall() {
		return ball;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public ArrayList<Player> getPlayersList() {
		return this.players;
	}

	public void incScoreA() {
		this.scoreA++;
	}

	public int getScoreA() {
		return scoreA;
	}

	public void incScoreB() {
		this.scoreB++;
	}

	public int getScoreB() {
		return scoreB;
	}
	
	public String getSCOREMsg() {
		StringBuilder sb = new StringBuilder();
		sb.append("SCORE\n");
		sb.append(String.valueOf(this.scoreA));
		sb.append(":");
		sb.append(String.valueOf(this.scoreB));
		return sb.toString();
	}
}
